package com.xxpt.user.advice;

import com.xxpt.common.auth.ValidationErrorCode;
import com.xxpt.common.exception.*;
import com.xxpt.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;

@Slf4j
@ControllerAdvice
public class ControllerExceptionAdvice {

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, Exception ex) {
        if(ex.getMessage().equals(ValidationErrorCode.IMPORT_EXCEL_HEAD_VERIF_ERROR.getCode())) {
            return Result.error(ValidationErrorCode.IMPORT_EXCEL_HEAD_VERIF_ERROR.getCode(), ValidationErrorCode.IMPORT_EXCEL_HEAD_VERIF_ERROR.getDesc());
        }
        log.error("服务器开小差了，请稍后再试！", ex);
        return thorwError(request, ValidationErrorCode.INTERNAL_SERVER_ERROR.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, SystemException ex) {
        log.error("系统异常，请稍后再试！", ex);
        return thorwError(request, ex.getCode(), ex.getMessage());
    }

    /**
     * 方法参数校验
     */
    @ExceptionHandler
    @ResponseBody
    public Object handleMethodArgumentNotValidException(HttpServletRequest request, MethodArgumentNotValidException ex) {
        log.error(ex.getMessage(), ex);
        return thorwError(request, ValidationErrorCode.ERROR_PARAM_ILLEGAL.getCode(), ex.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * ValidationException
     */
    @ExceptionHandler
    @ResponseBody
    public Object handleValidationException(HttpServletRequest request, ValidationException ex) {
        log.error(ex.getMessage(), ex);
        return thorwError(request, ValidationErrorCode.ERROR_PARAM_ILLEGAL.getCode(), ex.getMessage());
    }
    /**
     * ConstraintViolationException
     */
    @ExceptionHandler
    @ResponseBody
    public Object handleConstraintViolationException(HttpServletRequest request, ConstraintViolationException ex) {
        log.error(ex.getMessage(), ex);
        return thorwError(request, ValidationErrorCode.ERROR_PARAM_ILLEGAL.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, BussinessException ex) {
        log.error("业务异常,请稍后重试!", ex);
        return thorwError(request, ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, ForbiddenException ex) {
        log.error("不能操作异常,请稍后重试!", ex);
        return thorwError(request, ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, InternalServerErrorException ex) {
        log.error("内部服务器错误,请稍后重试!", ex);
        return thorwError(request, ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, NotFoundException ex) {
        log.error("未发现的异常,请稍后重试!", ex);
        return thorwError(request, ex.getCode(), ex.getMessage());
    }

    @ExceptionHandler
    @ResponseBody
    public Object exceptionHandler(HttpServletRequest request, com.xxpt.common.exception.UnauthorizedException ex) {
        log.error("未授权异常,请稍后重试!", ex);
        return Result.error(ex.getCode(), ex.getMessage());
    }
    @ResponseBody
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public Object handlerMaxUploadSizeExceededException(MaxUploadSizeExceededException e){
        return Result.error("上传文件太大");
    }

    /**
     * 异常处理
     * @param request
     * @param code
     * @param msg
     * @return
     */
    private Object thorwError(HttpServletRequest request, String code, String msg) {
        if (StringUtils.isEmpty(code) && msg.length() > 50) {
            return Result.error(ValidationErrorCode.SYSTEM_INTERNAL_SERVER_ERROR.getCode(), ValidationErrorCode.SYSTEM_INTERNAL_SERVER_ERROR.getDesc());
        }
        return Result.error(code, msg);
    }
}